home *** CD-ROM | disk | FTP | other *** search
- /*====================
-
- Print to PICS. © B.Raoult 1992
-
- This file contains an example of a Print2Pict 3.0 extension.
- It saves printed pages in a PICS file.
-
- ====================*/
- #include "P2PX.h"
- #include "tools.h"
-
-
- #define OPTS 'OPTS' /* Type of our options resource */
- #define OPTS_ID 128 /* ID of our options resource */
-
- #define SPEED 2 /* Frames/Seconds input field in the options dialog */
- #define DELETE 3 /* Frames/Seconds input field in the options dialog */
- #define MOVIE 4
-
- #define FIRST_FRAME 128
- #define LAST_FRAME 163
-
- /*=======
-
- Prototypes
-
- =======*/
-
- OSErr GetFlags(P2PXPtr arg);
- OSErr DoInit(P2PXPtr arg);
- OSErr DoEnd(P2PXPtr arg);
- OSErr DoPutPage(P2PXPtr arg);
- OSErr DoOptOpen(P2PXPtr arg);
- OSErr DoOptEvent(P2PXPtr arg);
- OSErr DoOptItem(P2PXPtr arg);
- OSErr DoOptDone(P2PXPtr arg);
-
- /*=======
-
- Structure of INFO resource used in PICS files
-
- =======*/
-
- typedef struct {
-
- short color; /* Color picture */
- short depth; /* Depth of picture */
- short speed; /* Frames/seconds */
- short version; /* version */
- OSType creator; /* creator */
- long maxsize; /* size of largest picture */
-
- } Infos, *PInfos, **HInfos;
-
- /*=======
-
- Private data
-
- ========*/
-
- typedef struct {
-
- short resfile; /* reference number of the PICS file */
- short count; /* current image number */
- HInfos info; /* Handle to info resource */
- FSSpec fspec; /* Specs of the PICS file */
-
- } Globals, *PGlobals, **HGlobals;
-
- /*========
-
- Our options
-
- ========*/
-
- typedef struct {
-
- short speed; /* Frames/seconds */
- Boolean delete; /* Delete file if the user aborts the job */
-
- } Opts, *POpts, **HOpts;
-
- /*========
-
- Data for animation
-
- ========*/
-
- typedef struct {
-
- short frame; /* Current frame */
- long last; /* last time we draw a frame */
- Boolean ready; /* ready after first update */
- Boolean color; /* plot 'cicn' */
- Rect box; /* Where to draw the frames */
- long speed; /* Speed in 60th of seconds */
-
- } Anim, *PAnim, **HAnim;
-
-
- /*=======
-
- Usefull macro to access our globals
-
- ========*/
-
- #define G (**((HGlobals)(arg->data)))
- #define A (**((HAnim)(arg->data)))
- #define O (**o)
- #define I (**info)
-
- /*======================================================================================
-
- This is the entry point of the code resource.
- It simply dispatches the calls to the proper routine
-
- ======================================================================================*/
-
- pascal OSErr main(int msg,P2PXPtr arg)
- {
- int ret = noErr;
-
- switch (msg)
- {
- case getFlagsMsg:
- ret = GetFlags(arg);
- break;
-
- case initMsg:
- ret = DoInit(arg);
- break;
-
- case endMsg:
- ret = DoEnd(arg);
- break;
-
- case putPageMsg:
- ret = DoPutPage(arg);
- break;
-
- case optOpenMsg:
- ret = DoOptOpen(arg);
- break;
-
- case optEventMsg:
- ret = DoOptEvent(arg);
- break;
-
- case optItemMsg:
- ret = DoOptItem(arg);
- break;
-
- case optDoneMsg:
- ret = DoOptDone(arg);
- break;
-
-
- }
-
- return ret;
- }
-
- /*======================================================================================
-
- Get flags of the code resource.
-
- - It can be called at ANY TIME.
-
- - Most of the fields of the parameters will not be valid.
- However, unintialized fields will contain nulls.
-
- - Note that you can later change the values of the flags
- in any other calls.
-
- ======================================================================================*/
-
- OSErr GetFlags(P2PXPtr arg)
- {
- arg->flags =
- CAN_PREVIEW + /* Preview is OK */
- ENVIRONMENT_OK + /* We can run on all Macs */
- WANT_FILE_NAMES + /* Wants the file names to save pages */
- HAS_OWN_OPTIONS ; /* We have some options */
-
- return noErr;
- }
-
- /*======================================================================================
-
- Called when the application calls PrOpenDoc().
- We allocate the handles needed for our globals.
-
- ======================================================================================*/
-
- OSErr DoInit(P2PXPtr arg)
- {
- HInfos info;
- HOpts o;
-
- /* Allocate some space four our globals */
-
- if(!(arg->data = NewHandleClear(sizeof(Globals))))
- return iMemFullErr;
-
-
- /* Allocate some space for the INFO structure */
-
- if(!(info = (HInfos)NewHandleClear(sizeof(Infos))))
- return iMemFullErr;
-
- /* Get our options */
-
- if(!(o = (HOpts)GetResource(OPTS,OPTS_ID)))
- return ResError();
-
-
- G.resfile = -1; /* The PICS file is not yet opened */
- G.count = 128; /* PICT resources start from 128 in a PICS file */
- G.info = info; /* Save the INFO structure */
-
- I.maxsize = 0; /* No pictures yet */
- I.creator = arg->creator; /* Use the creator chosen by the user */
- I.speed = O.speed; /* Use the speed chosen by the use */
-
- return noErr; /* All OK... */
- }
-
- /*======================================================================================
-
- End of print. Called from PrOpenDoc() if everything OK.
- Can be called at any time if something went wrong, so
- check if the private data is valid.
-
- ======================================================================================*/
-
-
- OSErr DoEnd(P2PXPtr arg)
- {
- int save = CurResFile(); /* Save the current resource file */
- OSErr retCode = noErr; /* be optimistic */
- HOpts o = (HOpts)GetResource(OPTS,OPTS_ID); /* Get our options record */
- Boolean ok = TRUE; /* If not, delete the file */
-
- if(arg->data) /* Did we have memory ? */
- {
-
- HInfos info = G.info; /* Recover the INFO structure */
-
- if(G.resfile != -1) /* Did we open any files ? */
- {
- UseResFile(G.resfile);
-
- if((arg->error == noErr) && info)
- {
-
- /* Add the INFO resource to the PICS file, check for error */
-
- AddResource(info,'INFO',128,"\p"); retCode = retCode?retCode:ResError();
- WriteResource(info); retCode = retCode?retCode:ResError();
- UpdateResFile(G.resfile); retCode = retCode?retCode:ResError();
-
- }
-
- if(retCode != noErr)
- ok = FALSE;
-
- }
- CloseResFile(G.resfile);
-
-
- /* Now let's do some clean up */
-
- if(info)
- DisposHandle(info);
-
- /* If an error was reported, we need to delete the file */
-
- if(arg->error != iPrAbort && arg->error != noErr)
- ok = FALSE;
-
- /* If this error is iPrAbort (user cancel) delete the file
- according to the options */
-
- if(o && O.delete)
- if(arg->error == iPrAbort)
- ok = FALSE;
-
- /* If something went wrong, don't leave incomplete files around */
-
- if(!ok)
- FSpDelete(&arg->fspec);
-
- DisposHandle(arg->data);
-
- }
-
- /* Restore current resource file */
- UseResFile(save);
-
- return retCode;
- }
-
- /*======================================================================================
-
- Process a page. Called when the application calls PrClosePage().
- Create the PICS file if it is the first time in.
- Add the picture as a PICT resource.
-
- ======================================================================================*/
-
- OSErr DoPutPage(P2PXPtr arg)
- {
- int save = CurResFile();
- OSErr retCode = noErr;
- HInfos info;
-
- /* No luck... */
-
- if(!(arg->data))
- return -1;
-
- if(!(arg->pict))
- return -1;
-
- info = G.info;
-
- /* First time in */
-
- if(G.resfile == -1)
- {
-
- /* Delete previous file if any */
-
- if(retCode = FSpDelete(&arg->fspec))
- if(retCode != fnfErr)
- return retCode;
-
- /* Create the file, giving it the right Creator and File type.*/
-
- FSpCreateResFile(&arg->fspec, arg->creator, 'PICS',arg->script);
- if(retCode = ResError())
- return retCode;
-
- /* Save the file spec if we need to delete it later */
-
- G.fspec = arg->fspec;
-
- /* Open the resoure file */
-
- G.resfile = FSpOpenResFile(&arg->fspec,fsRdWrPerm);
- if(G.resfile == -1)
- return ResError();
-
- /* We don't want any more file names */
-
- arg->flags &= ~WANT_FILE_NAMES;
-
- /* Fill the rest of the INFO structure */
-
- /* Are the PICTs in color ? */
-
- I.color = arg->color;
-
- /* If yes, get the depth of the printing port */
- if(arg->color)
- {
- PixMapHandle pix = ((CGrafPtr)(arg->port))->portPixMap;
- I.depth = (**pix).pixelSize;
- }
- else
- I.depth = 1;
- }
-
-
- /* Now save the current page as a PICT resource */
-
- UseResFile(G.resfile);
-
- AddResource(arg->pict,'PICT',(G.count)++,"\p"); retCode = retCode?retCode:ResError();
- SetResAttrs(arg->pict,resPurgeable); retCode = retCode?retCode:ResError();
- ChangedResource(arg->pict); retCode = retCode?retCode:ResError();
- WriteResource(arg->pict); retCode = retCode?retCode:ResError();
- UpdateResFile(G.resfile); retCode = retCode?retCode:ResError();
-
- /* Detache it so Print2Pict can kill it */
-
- DetachResource(arg->pict);
-
- /* Update maxsize in INFO structure */
-
- if(GetHandleSize(arg->pict)>I.maxsize)
- I.maxsize = GetHandleSize(arg->pict);
-
- /* Restore current resource file */
-
- UseResFile(save);
-
- return retCode;
-
- }
-
- /*======================================================================================
-
- Initialize the options dialog. Allocate some memory for the animation,
- initialize the dialog items.
-
- ======================================================================================*/
-
- OSErr DoOptOpen(P2PXPtr arg)
- {
- HOpts o = (HOpts)GetResource(OPTS,OPTS_ID); /* Get our options record */
- HAnim a;
-
- /* Something went wrong */
-
- if(!o)
- return ResError();
-
- /* Set the frames/seconds text field */
-
- if(O.speed <1 )
- O.speed = 1;
-
-
- /* Initalize the dialog items, Remember to skip the Print2Pict items */
-
- Long2Dialog(arg->dlog,arg->skip + SPEED,(long)O.speed);
- SetCheck(arg->dlog,arg->skip + DELETE,O.delete);
-
- /* Allocate some private storage for the animation */
-
- a = (HAnim)NewHandleClear(sizeof(Anim));
-
- /* No big deal if not enough memory */
-
- if(a)
- {
- /* Store the handle in the parameter block */
-
- arg->data = (Handle)a;
-
- /* Save the rectangle for the animation */
-
- A.box = GetItemR(arg->dlog,arg->skip + MOVIE);
-
- A.frame = FIRST_FRAME;
- A.speed = 60 / O.speed; /* Time between frams in 60th of seconds */
- A.color = HasColor(); /* Color QuickDraw is there... */
- }
-
- return noErr;
-
-
- }
-
- /*======================================================================================
-
- Called from the ModalDialog filter procedure. We handle use the null events
- to run the animation.
-
- ======================================================================================*/
-
- OSErr DoOptEvent(P2PXPtr arg)
- {
- Rect r;
-
- if(arg->data)
- {
- switch(arg->event->what)
- {
-
- case updateEvt:
-
- if(arg->event->message == (long)arg->dlog)
- {
- /* wait first update before starting the animation */
-
- A.ready = TRUE;
-
- /* Draw a frame around the rectangle */
-
- r = A.box;
- InsetRect(&r,-1,-1);
- FrameRect(&r);
- }
-
- break;
-
- case nullEvent:
-
- if(A.ready)
- {
- long now = TickCount();
- Rect r;
- CIconHandle h;
-
- /* If the time is elapsed */
-
- if( now-A.last >= A.speed)
- {
- A.last = now;
- r= A.box;
-
- /* Plot cicn if ColorQD is available, otherwise plot ICON */
-
- if(A.color)
- {
- h = GetCIcon(A.frame);
- PlotCIcon(&r,h);
- DisposCIcon(h);
- }
- else
- PlotIcon(&r,GetIcon(A.frame));
-
-
- /* Move to next frame */
-
- A.frame++;
-
- if(A.frame>LAST_FRAME)
- A.frame = FIRST_FRAME;
- }
- }
- break;
- }
- }
-
- return noErr;
- }
-
- /*======================================================================================
-
- Called with the item returned by ModalDialog.
-
- ======================================================================================*/
-
-
- OSErr DoOptItem(P2PXPtr arg)
- {
- long speed;
-
- switch(arg->item - arg->skip)
- {
- /* Click in the "delete" checkbox */
-
- case DELETE:
- ClickCheck(arg->dlog,arg->item);
- break;
-
- /* The "speed" text field as been modified */
-
- case SPEED:
-
- speed = Dialog2Long(arg->dlog,arg->item);
-
- if(speed<1)
- speed = 1;
-
- /* Change the speed of the animation with the new value */
-
- if(arg->data)
- A.speed = 60/speed;
-
- break;
- }
-
- return noErr;
- }
-
- /*======================================================================================
-
- End of option dialog. Release use memory and save the changes.
-
- ======================================================================================*/
-
- OSErr DoOptDone(P2PXPtr arg)
- {
- HOpts o = (HOpts)GetResource(OPTS,OPTS_ID); /* Get our options record */
- long newspeed;
- Boolean delete;
- HAnim a;
- OSErr retCode = noErr;
-
- /* Something went wrong */
-
- if(!o)
- {
- if(arg->data)
- DisposHandle(arg->data);
- return ResError();
- }
-
- /* Get the new values */
-
- newspeed = Dialog2Long(arg->dlog,arg->skip + SPEED);
- delete = GetCheck(arg->dlog,arg->skip + DELETE);
-
- /* If the user changed the value, update the record */
-
- if(O.speed != newspeed || O.delete != delete)
- {
- if(newspeed <1 )
- newspeed = 1;
-
- O.speed = newspeed;
- O.delete = delete;
- ChangedResource(o);
- WriteResource(o);
- UpdateResFile(HomeResFile(o));
- retCode = ResError();
- }
-
- /* Realease used memory */
- if(arg->data)
- {
- /* Because we draw outside of an item, we must clear it ourselves */
-
- Rect r = A.box;
- InsetRect(&r,-1,-1);
- EraseRect(&r);
-
- DisposHandle(arg->data);
- }
-
- return retCode;
- }
-
-
-
-